package com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl.foura;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.algo.cooperation.common.BaseResult;
import com.alibaba.algo.cooperation.common.PagerEntity;
import com.alibaba.algo.cooperation.feign.service.EmployeeFeignService;
import com.alibaba.algo.cooperation.feign.service.OrgFeignService;
import com.alibaba.algo.cooperation.feign.service.RoleFeignService;
import com.alibaba.algo.cooperation.feign.service.UserFeignService;
import com.alibaba.algo.cooperation.feign.vo.req.*;
import com.alibaba.algo.cooperation.feign.vo.res.*;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.gts.bpaas.framework.api.rest.dto.ResultResponse;
import com.aliyun.gts.delivery.enterprise.sdk.common.PageQuery;
import com.aliyun.gts.delivery.enterprise.sdk.common.PageResult;
import com.aliyun.gts.delivery.enterprise.sdk.orgaccount.in.AccountInfoQuery;
import com.aliyun.gts.delivery.enterprise.sdk.orgaccount.in.OrganizationInfoQuery;
import com.aliyun.gts.delivery.enterprise.sdk.orgaccount.in.OrganizationTreeQuery;
import com.aliyun.gts.delivery.enterprise.sdk.orgaccount.out.AccountInfo;
import com.aliyun.gts.delivery.enterprise.sdk.orgaccount.out.OrganizationInfo;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.WaterOrgAccountService;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.SessionUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.StringUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.common.UserGroup;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.common.impl.util.CollectionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;

/**
 * @Author: YeTaoRui
 * @Description:
 * @Date: Create in 10:55 2021/4/29
 * @Modify by:
 */
@Configuration
@ConditionalOnProperty(prefix = "xxl.sso",name = "enable",havingValue = "true")
@Service
@Slf4j
public class WaterOrgAccountServiceImpl  implements WaterOrgAccountService {

    @Autowired
    OrgFeignService orgFeignService;
    @Autowired
    UserFeignService userFeignService;

    @Autowired
    private RoleFeignService roleFeignService;

    @Autowired
    private EmployeeFeignService  employeeFeignService;

    /**
     * 获取当前用户信息
     *
     * @return
     */
    @Override
    public ResultResponse<AccountInfo> getCurrentAccountInfo() {

        return this.getAccountInfoByCode(SessionUtils.getUserCode());
    }

    /**
     * 根据用户编码获取用户信息
     *
     * @param s
     * @return
     */
    @Override
    public ResultResponse<AccountInfo> getAccountInfoByCode(String s) {
        // 不是数字型的userCode（如手动添加流程变量的办理人类型）就退出
        if(!org.apache.commons.lang3.StringUtils.isNumeric(s)) {
            return ResultResponse.succResult();
        }
        SelectUserInfoReqVO selectUserInfoReqVO = new SelectUserInfoReqVO();
        selectUserInfoReqVO.setUserId(Long.valueOf(s));
        BaseResult<RpcUserInfoVO> rpcUserInfoVOBaseResult = userFeignService.qryUserInfo(selectUserInfoReqVO);
        AccountInfo accountInfo = this.rpcUserConvert(rpcUserInfoVOBaseResult.getData(), s);
        return ResultResponse.succResult(accountInfo);
    }

    @Override
    public ResultResponse<PageResult<AccountInfo>> queryAccountInfoPage(PageQuery pageQuery, AccountInfoQuery accountInfoQuery) {
        return null;
    }

    @Override
    public ResultResponse<OrganizationInfo> getOrganizationByCode(String s) {
        GetOrgDetailReqVo getOrgDetailReqVo=new GetOrgDetailReqVo();
        //getOrgDetailReqVo.setOrgCode(s);
        getOrgDetailReqVo.setOrgId(Long.valueOf(s));
        BaseResult<FeignOrgDetailResponse> orgDetail=orgFeignService.getOrgDetail(getOrgDetailReqVo);
        FeignOrgDetailResponse feignOrgDetailResponse=orgDetail.getData();
        OrganizationInfo organizationInfo=new OrganizationInfo();
        if(feignOrgDetailResponse!=null){
            organizationInfo.setDisplayName(feignOrgDetailResponse.getOrgName());
            organizationInfo.setParentCode(feignOrgDetailResponse.getParentId().toString());
            organizationInfo.setOrgDescription(feignOrgDetailResponse.getOrgDesc());
        }
        return ResultResponse.succResult(organizationInfo);
    }

    @Override
    public ResultResponse<OrganizationInfo> getOrganizationTree(OrganizationTreeQuery organizationTreeQuery) {
        return null;
    }

    @Override
    public ResultResponse<PageResult<OrganizationInfo>> queryOrganizationInfoPage(PageQuery pageQuery, OrganizationInfoQuery organizationInfoQuery) {
        return null;
    }

    @Override
    public ResultResponse<List<OrganizationInfo>> getAccountBelongOrgByAccountCode(String s) {
        return null;
    }

    /**
     * 组织下的直接用户列表
     *
     * @param pageQuery
     * @param s
     * @return
     */
    @Override
    public ResultResponse<PageResult<AccountInfo>> getOrganizationMembersByOrgCode(PageQuery pageQuery, String s) {
        Map<String, String> params = new HashMap<>();
        params.put("orgCode", s);
        SelectOrgUserReqVO selectOrgUserReqVO = new SelectOrgUserReqVO();
        selectOrgUserReqVO.setOrgId(Long.valueOf(s));
        BaseResult<List<OrgUserInfoResVO>> listBaseResult = orgFeignService.qryUserListByOrgId(selectOrgUserReqVO);
        log.info("get users from userCenter By orgId-{}:{}",s,listBaseResult.getData());
        List<AccountInfo> userListConvert = this.userListConvert(listBaseResult.getData());
        if (Objects.isNull(userListConvert)){
            return ResultResponse.succResult();
        }
        PageResult<AccountInfo> objectPageResult = new PageResult<>();
        objectPageResult.setRows(userListConvert);
        objectPageResult.setTotal(userListConvert.size());
        return ResultResponse.succResult(objectPageResult);
    }

    @Override
    public ResultResponse<List<AccountInfo>> getAccountDirectSuperiors(String s) {
        return null;
    }

    @Override
    public ResultResponse<List<AccountInfo>> getAccountDirectSubordinates(String s) {
        return null;
    }

    @Override
    public ResultResponse<List<AccountInfo>> getAccountListByCode(String s) {
        SysOrgRoleReqVO sysOrgRoleReqVO=new SysOrgRoleReqVO();
        sysOrgRoleReqVO.setOrgCode(null);
        sysOrgRoleReqVO.setOrgId(null);
        try {
            sysOrgRoleReqVO.setRoleId(Long.valueOf(s));
        }
        catch(Exception e){
            log.info("the members of roldId must be integers, please check the input String:{}",s);
            return null;
        }
        sysOrgRoleReqVO.setRoleCode(null);
        List<SysOrgRoleReqVO> sysOrgRoleReqVOList=new ArrayList<>();
        sysOrgRoleReqVOList.add(sysOrgRoleReqVO);
        BaseResult<List<UserInfoResVO>> listBaseResult = orgFeignService.qryUserListByOrgAndRoleExtend(sysOrgRoleReqVOList);
        log.info("get users from userCenter By roldId-{}:{}",s,listBaseResult);
        List<UserInfoResVO> userInfoResVOList=listBaseResult.getData();
        if(Objects.isNull(userInfoResVOList)){
            return ResultResponse.succResult();
        }
        List<AccountInfo> accountInfos=new ArrayList<>();
        userInfoResVOList.forEach(it->{
            AccountInfo accountInfo=new AccountInfo();
            accountInfo.setCode(String.valueOf(it.getUserId()));
            accountInfo.setDisplayName(it.getUserName());
            accountInfo.setUsername(it.getUserName());
            accountInfos.add(accountInfo);
        });

        return ResultResponse.succResult(accountInfos);
    }

    /**
     * 获取根组织信息
     * @return
     */
    @Override
    public ResultResponse<OrganizationInfo> getRootOrganization() {
        SelectParentOrgReqVO selectParentOrgReqVO = new SelectParentOrgReqVO();
        selectParentOrgReqVO.setParentOrgId(0L);
        BaseResult<List<OrgInfoResVO>> listBaseResult = orgFeignService.qryOrgListByParentOrgId(selectParentOrgReqVO);
        List<OrganizationInfo> organizationInfos = this.orgListConvert(listBaseResult.getData());
        if (organizationInfos == null || CollectionUtil.isEmpty(organizationInfos)){
            return ResultResponse.succResult();
        }
        return ResultResponse.succResult(organizationInfos.get(0));
    }

    @Override
    public ResultResponse<OrganizationInfo> getAllOrgInfo() {
        return null;
    }

    /**
     * @param s
     * @return
     */
    @Override
    public ResultResponse<List<OrganizationInfo>> getOrganizationInfoByParentCode(String s) {
        Map<String, String> params = new HashMap<>();
        params.put("orgCode", s);
        SelectParentOrgReqVO selectParentOrgReqVO = new SelectParentOrgReqVO();
        selectParentOrgReqVO.setParentOrgId(Long.valueOf(s));
        BaseResult<List<OrgInfoResVO>> listBaseResult = orgFeignService.qryOrgListByParentOrgId(selectParentOrgReqVO);
        //对象转换
        List<OrganizationInfo> organizationInfos = this.orgListConvert(listBaseResult.getData());
        return ResultResponse.succResult(organizationInfos);
    }

    @Override
    public ResultResponse<List<AccountInfo>> getAllUserInfo(Integer integer) {
        return null;
    }

    private OrganizationInfo convert(OrgInfoResVO vo){
        if (Objects.isNull(vo)){
            return null;
        }
        OrganizationInfo organizationInfo = new OrganizationInfo();
        organizationInfo.setCode(String.valueOf(vo.getOrgId()));
        organizationInfo.setDisplayName(vo.getOrgName());
        return organizationInfo;
    }

    private List<OrganizationInfo> orgListConvert(List<OrgInfoResVO> voList){
        if (CollectionUtil.isEmpty(voList)){
            return null;
        }
        List<OrganizationInfo> organizationInfos = voList.stream().map(tmp -> {
            return this.convert(tmp);
        }).collect(Collectors.toList());
        return organizationInfos;
    }

    private AccountInfo userConvert(OrgUserInfoResVO orgUserInfoResVO){
        AccountInfo accountInfo = new AccountInfo();
        accountInfo.setCode(String.valueOf(orgUserInfoResVO.getUserId()));
        accountInfo.setUsername(orgUserInfoResVO.getUserName());
        accountInfo.setDisplayName(orgUserInfoResVO.getUserName());
        return accountInfo;
    }
    private List<AccountInfo> userListConvert(List<OrgUserInfoResVO> userInfoResVOList){
        if (CollectionUtil.isEmpty(userInfoResVOList)){
            return null;
        }
        List<AccountInfo> accountInfos = userInfoResVOList.stream().map(tmp -> {
           return this.userConvert(tmp);
        }).collect(Collectors.toList());
        return accountInfos;
    }

    private AccountInfo rpcUserConvert(RpcUserInfoVO rpcUserInfoVOBaseResult,String userId){
        if (Objects.isNull(rpcUserInfoVOBaseResult)){
            return null;
        }
        AccountInfo accountInfo = new AccountInfo();
        accountInfo.setUsername(rpcUserInfoVOBaseResult.getUserName());
        accountInfo.setCode(userId);
        accountInfo.setDisplayName(rpcUserInfoVOBaseResult.getUserName());
        accountInfo.setDisplayName(rpcUserInfoVOBaseResult.getUserName());
        accountInfo.setMobilePhone(rpcUserInfoVOBaseResult.getMobilePhone());
        accountInfo.setEmail(rpcUserInfoVOBaseResult.getEmail());
        Map map = JSONObject.parseObject(JSONObject.toJSONString(rpcUserInfoVOBaseResult), Map.class);
        List<UserOrgResVO> userOrgList = rpcUserInfoVOBaseResult.getOrgList();
        if (Objects.nonNull(userOrgList) && userOrgList.size() > 0){
            StringBuffer sbf = new StringBuffer();
            for (int i = 0; i < userOrgList.size(); i++) {
                if (i > 0){
                    sbf.append(",");
                }
                sbf.append(userOrgList.get(i).getOrgId());
            }
            map.put("ORG_CODE", sbf.toString());
        }
        accountInfo.setExtentAttributes(map);
        return accountInfo;

    }

    @Override
    public ResultResponse<List<AccountInfo>> getAccountByNameFuzzy(String username) {
        if (StringUtils.isEmpty(username)){
            return ResultResponse.succResult();
        }
        SelectUserListReqVO selectUserListReqVO = new SelectUserListReqVO();
        selectUserListReqVO.setUserName(username);
        BaseResult<List<UserInfoResVO>> listBaseResult = userFeignService.qryUserList(selectUserListReqVO);
        List<UserInfoResVO> userInfoResVOList = listBaseResult.getData();
        if (Objects.isNull(userInfoResVOList)){
            return ResultResponse.succResult();
        }

        List<AccountInfo> collect = userInfoResVOList.stream().map(tmp -> {
            AccountInfo accountInfo = new AccountInfo();
            accountInfo.setCode(tmp.getEmployeeCode());
            accountInfo.setUsername(tmp.getUserName());
            accountInfo.setDisplayName(tmp.getUserName());
            Map<String,Object> temp=new HashMap<>();
            temp.put("USER_ID",String.valueOf(tmp.getUserId()));
            temp.put("ORG_CODE","***");
            accountInfo.setExtentAttributes(temp);
            accountInfo.setMobilePhone("*********");
            return accountInfo;
        }).collect(Collectors.toList());
        return ResultResponse.succResult(collect);
    }

    @Override
    public ResultResponse<List<UserGroup>> getAllUserGroupList() {
        BaseResult<List<RoleInfoResVO>>  roleInfosResult = roleFeignService.qryRoleList();
        List<RoleInfoResVO> data  =  roleInfosResult.getData();
        if (CollectionUtil.isNotEmpty(data)){
            List<UserGroup> collect = data.stream().map(userGroupInfoResVO -> {
                UserGroup userGroup = new UserGroup();
                userGroup.setGroupId(userGroupInfoResVO.getRoleId()+"");
                userGroup.setGroupName(userGroupInfoResVO.getRoleName());
                return userGroup;
            }).collect(Collectors.toList());
            return ResultResponse.succResult(collect);
        }
        return  ResultResponse.succResult(new ArrayList<>());
    }

    @Override
    public ResultResponse<List<OrganizationInfo>> getRootOrg() {
        SelectParentOrgReqVO selectParentOrgReqVO = new SelectParentOrgReqVO();
        selectParentOrgReqVO.setParentOrgId(0L);
        BaseResult<List<OrgInfoResVO>> listBaseResult = orgFeignService.qryOrgListByParentOrgId(selectParentOrgReqVO);
        List<OrganizationInfo> organizationInfos = this.orgListConvert(listBaseResult.getData());
        if (organizationInfos == null || CollectionUtil.isEmpty(organizationInfos)){
            return ResultResponse.succResult();
        }
        return ResultResponse.succResult(organizationInfos);
    }

}
